import React, { useEffect, useMemo, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import _ from 'lodash';
import {
  LinearProgress,
} from '@mui/material';
import { DataGrid } from '@mui/x-data-grid';
import { useHistory, useLocation } from 'react-router-dom';
import { getUrlParam } from 'functions';
import { styled } from '@mui/material/styles';
import {
  CustomFooter,
  CustomPagination,
  CustomToolbar,
  ChecklistsNoRowsOverlay,
} from 'components/Checklists/ChecklistsTable/TableComponents';
import { editLocalStorageItem } from 'functions/localStorage';
import ChecklistModal from 'components/Checklists/ChecklistModal';
import ChecklistMultiFilterPopover from 'components/Checklists/ChecklistMultiFilterPopover';
import RecycleBin from 'components/Checklists/RecycleBin';
import { getChecklist } from 'routes/checklists';
import showAlert from 'functions/showAlert';
import { setNeedToUpdateChecklistsTable } from 'redux/actions/app';
import localizedTextsMap from '../localizationRU';
import routerPaths from '../../../routerPaths';
import tableColumns from './TableColumns';
import ChecklistsTableSettings from './ChecklistsTableSettings';
import ChecklistDeleteDialog from './ChecklistDeleteDialog';
import ChecklistWarningDialog from './ChecklistWarningDialog';
import { work_statuses, defaultTableRowHeight } from '../../../constants';
import { warningMessages as w } from '../../../alertMessages';

const StyledDataGrid = styled(DataGrid)(() => ({
  '& .MuiDataGrid-cell': {
    whiteSpace: 'normal',
    fontSize: 13,
    cursor: 'default',
  },
  '&.MuiDataGrid-root .MuiDataGrid-cell:focus': {
    outline: 'none',
  },
}));

export default function ChecklistsTable(props) {
  const {
    project,
    rowsData,
    setRowsData,
    checklistsTableData,
    setChecklistsTableData,
    isLoadingRowsData,
    setIsLoadingRowsData,
    decryptedAccountData,
    appSettings,
    disableAnnulled,
    permissions,
  } = props;

  const dispatch = useDispatch();
  const history = useHistory();
  const location = useLocation();
  const isNeedToUpdate = useSelector((state) => state.app.isNeedToUpdateChecklistsTable);
  const [rowData, setRowData] = useState(undefined);
  const [checklistModalType, setChecklistModalType] = useState(undefined);
  const [selectionModel, setSelectionModel] = useState([]);
  const [openChecklistModal, setOpenChecklistModal] = useState(false);
  const [openDeleteDialog, setOpenDeleteDialog] = useState(false);
  const [openRecycleBin, setOpenRecycleBin] = useState(false);
  const [openFilterModal, setOpenFilterModal] = useState(false);
  const [openSettingsPopover, setOpenSettingsPopover] = useState(false);
  const [filterLength, setFilterLength] = useState(0);
  const [filterAnchor, setFilterAnchor] = useState(null);
  const [settingsAnchor, setSettingsAnchor] = useState(null);
  const [checkboxMultiselect, setCheckboxMultiselect] = useState(false);
  const [tableHeaderCheckbox, setTableHeaderCheckbox] = useState('none');
  const [isLoadingRecycleBin, setIsLoadingRecycleBin] = useState(false);
  const [progressInterval, setProgressInterval] = useState(0);
  const [rowsDataCount, setRowsDataCount] = useState(undefined);
  const [dbChecklistsCount, setDbChecklistsCount] = useState(undefined);
  const [checklistByUrl, setChecklistByUrl] = useState(false);
  const [notPrintedChecklistsArr, setNotPrintedChecklistsArr] = useState([]);
  const [openChecklistWarningDialog, setOpenChecklistWarningDialog] = useState(false);
  const [forceUpdateRowData, setForceUpdateRowData] = useState(undefined);
  const [page, setPage] = useState(undefined);

  const linkNumber = getUrlParam('number');

  const expandColumns = appSettings.checklists.expand_columns;
  const columns = useMemo(() => tableColumns(expandColumns, decryptedAccountData),
    [rowsData, appSettings]);

  const initializeChecklistModal = () => {
    history.push(`${routerPaths.Checklists.getUrl(project.urls_path)}?number=${rowData.checklist_number}`);
    setChecklistModalType('edit');
    setOpenChecklistModal(true);
  };

  useEffect(() => {
    if (rowsData && rowsData.length > 0) {
      setRowsDataCount(rowsData.length);
      const checklistsArray = rowsData
        .filter((o) => (o.user && o.user.id) === decryptedAccountData.id
            && o.printed === false
            && (o.work_status && o.work_status.id) === work_statuses[0].id);
      setNotPrintedChecklistsArr(checklistsArray);
    }
  }, [rowsData]);

  useEffect(() => {
    if (rowData && forceUpdateRowData) {
      initializeChecklistModal();
      setForceUpdateRowData(false);
    }
  }, [rowData]);

  useEffect(() => {
    if (isNeedToUpdate && rowData && rowsData && rowsData.length > 0) {
      const row = rowsData.find((o) => o.id === rowData.id);
      if (row) {
        setRowData(row);
      }
    }
  }, [isNeedToUpdate, rowsData]);

  useEffect(() => {
    if (!rowData && linkNumber && rowsData && rowsData.length > 0) {
      const urlObject = rowsData.find((o) => o.checklist_number === linkNumber);
      if (urlObject) {
        setChecklistByUrl(true);
        setRowData(urlObject);
        setSelectionModel([urlObject.id]);
        setChecklistModalType('edit');
        setOpenChecklistModal(true);
      } else {
        history.push('404');
      }
    }
  }, [location, rowsData]);

  const handleOpenFilter = (event) => {
    setOpenFilterModal(true);
    setFilterAnchor(event.currentTarget);
  };

  const handleOpenSettings = (event) => {
    setOpenSettingsPopover(true);
    setSettingsAnchor(event.currentTarget);
  };

  const handleSwitchColumns = (event) => {
    if (event.target.checked === true) {
      editLocalStorageItem({
        localStorageItemKey: 'app_settings',
        editableKey: 'expand_columns',
        newValue: true,
      });
    } else if (event.target.checked === false) {
      editLocalStorageItem({
        localStorageItemKey: 'app_settings',
        editableKey: 'expand_columns',
        newValue: false,
      });
    }
  };

  const handleSwitchAnnulled = (event) => {
    if (event.target.checked === true) {
      editLocalStorageItem({
        localStorageItemKey: 'app_settings',
        editableKey: 'disable_annulled',
        newValue: true,
      });
      dispatch(setNeedToUpdateChecklistsTable(true));
    } else if (event.target.checked === false) {
      editLocalStorageItem({
        localStorageItemKey: 'app_settings',
        editableKey: 'disable_annulled',
        newValue: false,
      });
      dispatch(setNeedToUpdateChecklistsTable(true));
    }
  };

  const handleOpenAdd = () => {
    if (notPrintedChecklistsArr.length === 0) {
      setChecklistModalType('add');
      setOpenChecklistModal(true);
    } else {
      setOpenChecklistWarningDialog(true);
    }
  };

  const handleOpenEdit = () => {
    if (rowData) {
      getChecklist({ id: rowData.id, project_id: project.id }).then((row) => {
        const isObjectsEqual = _.isEqual(rowData, row.checklist);
        if (isObjectsEqual) {
          setDbChecklistsCount(row.checklists_count);
          initializeChecklistModal();
        } else if (!isObjectsEqual && rowData.deleted === row.checklist.deleted) {
          setDbChecklistsCount(row.checklists_count);
          setForceUpdateRowData(true);
          dispatch(setNeedToUpdateChecklistsTable(true));
        } else if (!isObjectsEqual && rowData.deleted !== row.checklist.deleted) {
          dispatch(setNeedToUpdateChecklistsTable(true));
          showAlert('warning', w.WARN_DEL_SEL_CHECKLIST);
        }
      }).catch((error) => showAlert('error', error));
    }
  };

  const handleClickDelete = (event) => {
    if (!(event.metaKey || event.ctrlKey) && selectionModel.length > 0) {
      if (checkboxMultiselect) {
        setOpenDeleteDialog(true);
        setProgressInterval(Number(100 / selectionModel.length));
      } else {
        getChecklist({ id: rowData.id, project_id: project.id }).then((row) => {
          const isObjectsEqual = _.isEqual(rowData, row.checklist);
          if (isObjectsEqual) {
            setOpenDeleteDialog(true);
          } else if (!isObjectsEqual && rowData.deleted !== row.checklist.deleted) {
            dispatch(setNeedToUpdateChecklistsTable(true));
            showAlert('warning', w.WARN_DEL_SEL_CHECKLIST);
          }
        }).catch((error) => showAlert('error', error));
      }
    }
    if ((event.metaKey || event.ctrlKey) && permissions
      ?.isAdminUserAllowed && checkboxMultiselect === false) {
      setCheckboxMultiselect(true);
      setTableHeaderCheckbox('true');
    } else if ((event.metaKey || event.ctrlKey) && checkboxMultiselect === true) {
      setRowData(undefined);
      setSelectionModel([]);
      setCheckboxMultiselect(false);
      setTableHeaderCheckbox('none');
      setProgressInterval(0);
    }
  };

  const handleOpenRecycleBin = () => {
    setOpenRecycleBin(true);
  };

  const customToolbar = () => CustomToolbar(
    handleOpenFilter,
    handleOpenSettings,
    handleOpenAdd,
    handleOpenEdit,
    handleOpenRecycleBin,
    handleClickDelete,
    filterLength,
    checkboxMultiselect,
    rowsData,
    rowData,
    isLoadingRowsData,
    decryptedAccountData,
    selectionModel,
    permissions,
  );
  const customFooter = () => CustomFooter({
    rowData,
    setRowData,
    checkboxMultiselect,
    selectionModel,
    setSelectionModel,
    checklistByUrl,
    setChecklistByUrl,
    page,
    setPage,
  });
  const customPagination = () => CustomPagination(isLoadingRowsData, isLoadingRecycleBin);
  const checklistsNoRowsOverlay = () => ChecklistsNoRowsOverlay(filterLength);

  const onSelectionModelChange = (selection) => {
    if (checkboxMultiselect === false) {
      const selectionSet = new Set(selectionModel);
      const result = selection.filter((r) => !selectionSet.has(r));
      const selectedRowData = rowsData.filter((row) => result[0] === row.id)[0];
      setSelectionModel(result);
      setRowData(selectedRowData);
    } else if (checkboxMultiselect === true) {
      if (selection.length + 1 && selection.length === 1) {
        const selectedRowData = rowsData.filter((row) => selection[0] === row.id)[0];
        setRowData(selectedRowData);
      } else {
        setRowData('checkboxMultiselect');
      }
      setSelectionModel(selection);
    }
  };

  return (
    <div>
      <StyledDataGrid
        rows={rowsData}
        columns={columns}
        loading={isLoadingRowsData}
        sx={{
          height: '92vh',
          '& .MuiDataGrid-columnHeaderCheckbox .MuiDataGrid-columnHeaderTitleContainer': {
            display: tableHeaderCheckbox,
          },
          '.abortedChecklistRow': {
            bgcolor: 'rgba(255,36,36,0.08)',
            '&:hover': {
              bgcolor: 'rgba(255,36,36,0.12)',
            },
          },
        }}
        components={{
          Toolbar: customToolbar,
          Footer: customFooter,
          Pagination: customPagination,
          NoRowsOverlay: checklistsNoRowsOverlay,
          LoadingOverlay: LinearProgress,
        }}
        pagination
        localeText={localizedTextsMap}
        getRowClassName={(params) => (params.row.work_status && params.row.work_status.label === 'Аннулирован' ? 'abortedChecklistRow' : '')}
        rowHeight={defaultTableRowHeight}
        isRowSelectable={() => !isLoadingRowsData}
        checkboxSelection
        selectionModel={selectionModel}
        onSelectionModelChange={onSelectionModelChange}
        autoPageSize
        disableColumnMenu
        hideFooterSelectedRowCount
      />
      <ChecklistMultiFilterPopover
        open={openFilterModal}
        setFilterLength={setFilterLength}
        rowsData={rowsData}
        setRowsData={setRowsData}
        columns={columns}
        handleClose={() => setOpenFilterModal(false)}
        anchorEl={filterAnchor}
      />
      <ChecklistsTableSettings
        open={openSettingsPopover}
        handleClose={() => setOpenSettingsPopover(false)}
        anchorEl={settingsAnchor}
        expandColumns={expandColumns}
        handleSwitchColumns={handleSwitchColumns}
        disableAnnulled={disableAnnulled}
        handleSwitchAnnulled={handleSwitchAnnulled}
      />
      {project && decryptedAccountData && (
        <ChecklistModal
          open={openChecklistModal}
          setOpenChecklistModal={setOpenChecklistModal}
          project={project}
          rowsDataCount={rowsDataCount}
          setRowsDataCount={setRowsDataCount}
          dbChecklistsCount={dbChecklistsCount}
          setDbChecklistsCount={setDbChecklistsCount}
          rowData={checklistModalType === 'edit' ? rowData : undefined}
          setRowData={setRowData}
          rowsData={rowsData}
          checklistsTableData={checklistsTableData}
          setChecklistsTableData={setChecklistsTableData}
          checklistModalType={checklistModalType}
          setSelectionModel={setSelectionModel}
          appSettings={appSettings}
          decryptedAccountData={decryptedAccountData}
          permissions={permissions}
        />
      )}
      <ChecklistDeleteDialog
        open={openDeleteDialog}
        handleClose={() => setOpenDeleteDialog(false)}
        selectedChecklistObject={selectionModel.length === 1 ? rowData : undefined}
        selectedChecklistsIds={selectionModel}
        checkboxMultiselect={checkboxMultiselect}
        whereFromDelete="table"
        setIsLoadingRowsData={setIsLoadingRowsData}
        progressInterval={progressInterval}
        decryptedAccountData={decryptedAccountData}
      />
      {notPrintedChecklistsArr.length > 0 && (
        <ChecklistWarningDialog
          open={openChecklistWarningDialog}
          handleClose={() => setOpenChecklistWarningDialog(false)}
          notPrintedChecklistsArr={notPrintedChecklistsArr}
          setChecklistModalType={setChecklistModalType}
          setOpenChecklistModal={setOpenChecklistModal}
          permissions={permissions}
        />
      )}
      <RecycleBin
        open={openRecycleBin}
        handleClose={() => setOpenRecycleBin(false)}
        StyledDataGrid={StyledDataGrid}
        project={project}
        customPagination={customPagination}
        isLoadingRecycleBin={isLoadingRecycleBin}
        setIsLoadingRecycleBin={setIsLoadingRecycleBin}
        decryptedAccountData={decryptedAccountData}
      />
    </div>
  );
}
